gtkcolorchooserprivate.h \
gtkcontainerprivate.h \
gtkcssanimatedvaluesprivate.h \
+ gtkcssanimationprivate.h \
gtkcssarrayvalueprivate.h \
gtkcssbgsizevalueprivate.h \
gtkcssbordervalueprivate.h \
gtkcomboboxtext.c \
gtkcontainer.c \
gtkcssanimatedvalues.c \
+ gtkcssanimation.c \
gtkcssarrayvalue.c \
gtkcssbgsizevalue.c \
gtkcssbordervalue.c \
#include "gtkcssanimatedvaluesprivate.h"
+#include "gtkcssanimationprivate.h"
#include "gtkcssarrayvalueprivate.h"
+#include "gtkcssenumvalueprivate.h"
#include "gtkcssnumbervalueprivate.h"
#include "gtkcssshorthandpropertyprivate.h"
#include "gtkcssstringvalueprivate.h"
#include "gtkcssstylepropertyprivate.h"
#include "gtkcsstransitionprivate.h"
#include "gtkstyleanimationprivate.h"
+#include "gtkstylepropertiesprivate.h"
#include "gtkstylepropertyprivate.h"
+#include "gtkstyleproviderprivate.h"
G_DEFINE_TYPE (GtkCssAnimatedValues, _gtk_css_animated_values, GTK_TYPE_CSS_COMPUTED_VALUES)
delays = _gtk_css_computed_values_get_value (computed, GTK_CSS_PROPERTY_TRANSITION_DELAY);
timing_functions = _gtk_css_computed_values_get_value (computed, GTK_CSS_PROPERTY_TRANSITION_TIMING_FUNCTION);
-
for (i = 0; i < GTK_CSS_PROPERTY_N_PROPERTIES; i++)
{
GtkStyleAnimation *animation;
}
}
+static GtkStyleAnimation *
+gtk_css_animated_values_find_animation (GtkCssAnimatedValues *values,
+ const char *name)
+{
+ GSList *list;
+
+ for (list = values->animations; list; list = list->next)
+ {
+ if (!GTK_IS_CSS_ANIMATION (list->data))
+ continue;
+
+ if (g_str_equal (_gtk_css_animation_get_name (list->data), name))
+ return list->data;
+ }
+
+ return NULL;
+}
+
+static void
+gtk_css_animated_values_start_css_animations (GtkCssAnimatedValues *values,
+ gint64 timestamp,
+ GtkStyleContext *context)
+{
+ GtkCssComputedValues *computed;
+ GtkStyleProviderPrivate *provider;
+ GtkCssValue *durations, *delays, *timing_functions, *animations;
+ GtkCssValue *iteration_counts, *directions, *play_states, *fill_modes;
+ guint i;
+
+ computed = GTK_CSS_COMPUTED_VALUES (values);
+
+ provider = _gtk_style_context_get_style_provider (context);
+ animations = _gtk_css_computed_values_get_value (computed, GTK_CSS_PROPERTY_ANIMATION_NAME);
+ durations = _gtk_css_computed_values_get_value (computed, GTK_CSS_PROPERTY_ANIMATION_DURATION);
+ delays = _gtk_css_computed_values_get_value (computed, GTK_CSS_PROPERTY_ANIMATION_DELAY);
+ timing_functions = _gtk_css_computed_values_get_value (computed, GTK_CSS_PROPERTY_ANIMATION_TIMING_FUNCTION);
+ iteration_counts = _gtk_css_computed_values_get_value (computed, GTK_CSS_PROPERTY_ANIMATION_ITERATION_COUNT);
+ directions = _gtk_css_computed_values_get_value (computed, GTK_CSS_PROPERTY_ANIMATION_DIRECTION);
+ play_states = _gtk_css_computed_values_get_value (computed, GTK_CSS_PROPERTY_ANIMATION_PLAY_STATE);
+ fill_modes = _gtk_css_computed_values_get_value (computed, GTK_CSS_PROPERTY_ANIMATION_FILL_MODE);
+
+ for (i = 0; i < _gtk_css_array_value_get_n_values (animations); i++)
+ {
+ GtkStyleAnimation *animation;
+ GtkCssKeyframes *keyframes;
+ const char *name;
+
+ name = _gtk_css_ident_value_get (_gtk_css_array_value_get_nth (animations, i));
+ if (g_ascii_strcasecmp (name, "none") == 0)
+ continue;
+
+ animation = gtk_css_animated_values_find_animation (values, name);
+ if (animation)
+ continue;
+
+ keyframes = _gtk_style_provider_private_get_keyframes (provider, name);
+ if (keyframes == NULL)
+ continue;
+
+ keyframes = _gtk_css_keyframes_compute (keyframes, context);
+
+ animation = _gtk_css_animation_new (name,
+ keyframes,
+ timestamp + _gtk_css_number_value_get (_gtk_css_array_value_get_nth (delays, i), 100) * G_USEC_PER_SEC,
+ _gtk_css_number_value_get (_gtk_css_array_value_get_nth (durations, i), 100) * G_USEC_PER_SEC,
+ _gtk_css_array_value_get_nth (timing_functions, i),
+ _gtk_css_direction_value_get (_gtk_css_array_value_get_nth (directions, i)),
+ _gtk_css_play_state_value_get (_gtk_css_array_value_get_nth (play_states, i)),
+ _gtk_css_fill_mode_value_get (_gtk_css_array_value_get_nth (fill_modes, i)),
+ _gtk_css_number_value_get (_gtk_css_array_value_get_nth (iteration_counts, i), 100));
+ values->animations = g_slist_prepend (values->animations, animation);
+ }
+}
+
/* PUBLIC API */
static void
gtk_css_animated_values_start_animations (GtkCssAnimatedValues *values,
gint64 timestamp,
- GtkCssComputedValues *source)
+ GtkCssComputedValues *source,
+ GtkStyleContext *context)
{
gtk_css_animated_values_start_transitions (values, timestamp, source);
+ gtk_css_animated_values_start_css_animations (values, timestamp, context);
}
GtkCssComputedValues *
_gtk_css_animated_values_new (GtkCssComputedValues *computed,
GtkCssComputedValues *source,
- gint64 timestamp)
+ gint64 timestamp,
+ GtkStyleContext *context)
{
GtkCssAnimatedValues *values;
GtkCssValue *value;
g_return_val_if_fail (GTK_IS_CSS_COMPUTED_VALUES (computed), NULL);
g_return_val_if_fail (GTK_IS_CSS_COMPUTED_VALUES (source), NULL);
+ g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), NULL);
values = g_object_new (GTK_TYPE_CSS_ANIMATED_VALUES, NULL);
GTK_CSS_COMPUTED_VALUES (values)->depends_on_color = _gtk_bitmask_copy (computed->depends_on_color);
GTK_CSS_COMPUTED_VALUES (values)->depends_on_font_size = _gtk_bitmask_copy (computed->depends_on_font_size);
- gtk_css_animated_values_start_animations (values, timestamp, source);
+ gtk_css_animated_values_start_animations (values, timestamp, source, context);
ignore = _gtk_css_animated_values_advance (values, timestamp);
_gtk_bitmask_free (ignore);
GtkCssComputedValues * _gtk_css_animated_values_new (GtkCssComputedValues *computed,
GtkCssComputedValues *source,
- gint64 timestamp);
+ gint64 timestamp,
+ GtkStyleContext *context);
GtkBitmask * _gtk_css_animated_values_advance (GtkCssAnimatedValues *values,
gint64 timestamp) G_GNUC_WARN_UNUSED_RESULT;
--- /dev/null
+/*
+ * Copyright © 2012 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Benjamin Otte <otte@gnome.org>
+ */
+
+#include "config.h"
+
+#include "gtkcssanimationprivate.h"
+
+#include "gtkcsseasevalueprivate.h"
+
+#include <math.h>
+
+G_DEFINE_TYPE (GtkCssAnimation, _gtk_css_animation, GTK_TYPE_STYLE_ANIMATION)
+
+/* NB: Return value can be negative and +-Inf */
+static double
+gtk_css_animation_get_iteration (GtkCssAnimation *animation,
+ gint64 for_time_us)
+{
+ gint64 elapsed;
+ double iterations;
+
+ elapsed = for_time_us - animation->timestamp;
+ iterations = (double) elapsed / animation->duration;
+
+ return iterations;
+}
+
+static gboolean
+gtk_css_animation_is_executing_at_iteration (GtkCssAnimation *animation,
+ double iteration)
+{
+ switch (animation->fill_mode)
+ {
+ case GTK_CSS_FILL_NONE:
+ return iteration >= 0 && iteration <= animation->iteration_count;
+ case GTK_CSS_FILL_FORWARDS:
+ return iteration >= 0;
+ case GTK_CSS_FILL_BACKWARDS:
+ return iteration <= animation->iteration_count;
+ case GTK_CSS_FILL_BOTH:
+ return TRUE;
+ default:
+ g_return_val_if_reached (FALSE);
+ }
+}
+
+static double
+gtk_css_animation_get_progress_from_iteration (GtkCssAnimation *animation,
+ double iteration)
+{
+ double d;
+
+ iteration = CLAMP (iteration, 0, animation->iteration_count);
+
+ switch (animation->direction)
+ {
+ case GTK_CSS_DIRECTION_NORMAL:
+ if (iteration == animation->iteration_count)
+ return 1;
+ else
+ return iteration - floor (iteration);
+ case GTK_CSS_DIRECTION_REVERSE:
+ if (iteration == animation->iteration_count)
+ return 1;
+ else
+ return ceil (iteration) - iteration;
+ case GTK_CSS_DIRECTION_ALTERNATE:
+ d = floor (iteration);
+ if (fmod (d, 2))
+ return iteration - d;
+ else
+ return 1 + d - iteration;
+ case GTK_CSS_DIRECTION_ALTERNATE_REVERSE:
+ d = floor (iteration);
+ if (fmod (d, 2))
+ return 1 + d - iteration;
+ else
+ return iteration - d;
+ default:
+ g_return_val_if_reached (0);
+ }
+}
+
+static GtkBitmask *
+gtk_css_animation_set_values (GtkStyleAnimation *style_animation,
+ GtkBitmask *changed,
+ gint64 for_time_us,
+ GtkCssComputedValues *values)
+{
+ GtkCssAnimation *animation = GTK_CSS_ANIMATION (style_animation);
+ double iteration, progress;
+ guint i;
+
+ iteration = gtk_css_animation_get_iteration (animation, for_time_us);
+
+ if (!gtk_css_animation_is_executing_at_iteration (animation, iteration))
+ return changed;
+
+ progress = gtk_css_animation_get_progress_from_iteration (animation, iteration);
+ progress = _gtk_css_ease_value_transform (animation->ease, progress);
+
+ for (i = 0; i < _gtk_css_keyframes_get_n_properties (animation->keyframes); i++)
+ {
+ GtkCssValue *value;
+ guint property_id;
+
+ property_id = _gtk_css_keyframes_get_property_id (animation->keyframes, i);
+
+ value = _gtk_css_keyframes_get_value (animation->keyframes,
+ i,
+ progress,
+ _gtk_css_computed_values_get_value (values, i));
+ /* XXX: Is using 0 correct here? */
+ _gtk_css_computed_values_set_value (values, property_id, value, 0, NULL);
+ _gtk_css_value_unref (value);
+
+ changed = _gtk_bitmask_set (changed, property_id, TRUE);
+ }
+
+ return changed;
+}
+
+static gboolean
+gtk_css_animation_is_finished (GtkStyleAnimation *style_animation,
+ gint64 at_time_us)
+{
+ return FALSE;
+}
+
+static void
+gtk_css_animation_finalize (GObject *object)
+{
+ GtkCssAnimation *animation = GTK_CSS_ANIMATION (object);
+
+ g_free (animation->name);
+ _gtk_css_keyframes_unref (animation->keyframes);
+ _gtk_css_value_unref (animation->ease);
+
+ G_OBJECT_CLASS (_gtk_css_animation_parent_class)->finalize (object);
+}
+
+static void
+_gtk_css_animation_class_init (GtkCssAnimationClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkStyleAnimationClass *animation_class = GTK_STYLE_ANIMATION_CLASS (klass);
+
+ object_class->finalize = gtk_css_animation_finalize;
+
+ animation_class->set_values = gtk_css_animation_set_values;
+ animation_class->is_finished = gtk_css_animation_is_finished;
+}
+
+static void
+_gtk_css_animation_init (GtkCssAnimation *animation)
+{
+}
+
+GtkStyleAnimation *
+_gtk_css_animation_new (const char *name,
+ GtkCssKeyframes *keyframes,
+ gint64 start_time_us,
+ gint64 duration_us,
+ GtkCssValue *ease,
+ GtkCssDirection direction,
+ GtkCssPlayState play_state,
+ GtkCssFillMode fill_mode,
+ double iteration_count)
+{
+ GtkCssAnimation *animation;
+
+ g_return_val_if_fail (name != NULL, NULL);
+ g_return_val_if_fail (keyframes != NULL, NULL);
+ g_return_val_if_fail (ease != NULL, NULL);
+ g_return_val_if_fail (iteration_count >= 0, NULL);
+
+ animation = g_object_new (GTK_TYPE_CSS_ANIMATION, NULL);
+
+ animation->name = g_strdup (name);
+ animation->keyframes = _gtk_css_keyframes_ref (keyframes);
+ animation->timestamp = start_time_us;
+ animation->duration = duration_us;
+ animation->ease = _gtk_css_value_ref (ease);
+ animation->direction = direction;
+ animation->play_state = play_state;
+ animation->fill_mode = fill_mode;
+ animation->iteration_count = iteration_count;
+
+ return GTK_STYLE_ANIMATION (animation);
+}
+
+const char *
+_gtk_css_animation_get_name (GtkCssAnimation *animation)
+{
+ g_return_val_if_fail (GTK_IS_CSS_ANIMATION (animation), NULL);
+
+ return animation->name;
+}
--- /dev/null
+/*
+ * Copyright © 2012 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Benjamin Otte <otte@gnome.org>
+ */
+
+#ifndef __GTK_CSS_ANIMATION_PRIVATE_H__
+#define __GTK_CSS_ANIMATION_PRIVATE_H__
+
+#include "gtkstyleanimationprivate.h"
+
+#include "gtkcsskeyframesprivate.h"
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_CSS_ANIMATION (_gtk_css_animation_get_type ())
+#define GTK_CSS_ANIMATION(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_CSS_ANIMATION, GtkCssAnimation))
+#define GTK_CSS_ANIMATION_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_CSS_ANIMATION, GtkCssAnimationClass))
+#define GTK_IS_CSS_ANIMATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_CSS_ANIMATION))
+#define GTK_IS_CSS_ANIMATION_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_CSS_ANIMATION))
+#define GTK_CSS_ANIMATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CSS_ANIMATION, GtkCssAnimationClass))
+
+typedef struct _GtkCssAnimation GtkCssAnimation;
+typedef struct _GtkCssAnimationClass GtkCssAnimationClass;
+
+struct _GtkCssAnimation
+{
+ GtkStyleAnimation parent;
+
+ char *name;
+ GtkCssKeyframes *keyframes;
+ GtkCssValue *ease;
+ gint64 timestamp; /* elapsed time when paused, start time when playing (can be negative) */
+ gint64 duration; /* duration of 1 cycle */
+ GtkCssDirection direction;
+ GtkCssPlayState play_state;
+ GtkCssFillMode fill_mode;
+ double iteration_count;
+};
+
+struct _GtkCssAnimationClass
+{
+ GtkStyleAnimationClass parent_class;
+};
+
+GType _gtk_css_animation_get_type (void) G_GNUC_CONST;
+
+GtkStyleAnimation * _gtk_css_animation_new (const char *name,
+ GtkCssKeyframes *keyframes,
+ gint64 start_time_us,
+ gint64 duration_us,
+ GtkCssValue *ease,
+ GtkCssDirection direction,
+ GtkCssPlayState play_state,
+ GtkCssFillMode fill_mode,
+ double iteration_count);
+
+const char * _gtk_css_animation_get_name (GtkCssAnimation *animation);
+
+G_END_DECLS
+
+#endif /* __GTK_CSS_ANIMATION_PRIVATE_H__ */
animated = style_data_new ();
animated->store = _gtk_css_animated_values_new (style_data_lookup (context)->store,
previous,
- timestamp);
+ timestamp,
+ context);
if (_gtk_css_animated_values_is_finished (GTK_CSS_ANIMATED_VALUES (animated->store)))
{